#include "TaskQueue.h"

/**
 * TaskQueue implementation
 */


/**
 * @brief 互斥进行打印操作
 */
mutex coutMutex;


/**
 * @param capa
 */
TaskQueue::TaskQueue(size_t capa) 
: _capacity(capa)
, _que()
, _mtx()
, _condi()
, _isExit(false)
{}

TaskQueue::~TaskQueue() {}  // 暂无用处

/**
 * @param val
 * @return void
 */
void TaskQueue::push(ElemType && val) { // 使用右值！！
    unique_lock<mutex> uniLk{_mtx}; // 自动上锁

    while(full()){
        _condi.wait(uniLk);
    }

    if(val){ // 非空对象
        _que.push(std::move(val));  // 触发移动构造
        _condi.notify_all();  // 唤醒因队列空而陷入等待的子线程
    }

    return;
}

/**
 * @return ElemType
 */
ElemType TaskQueue::pop() {
    unique_lock<mutex> uniLk{_mtx}; // 自动上锁

    while(empty() && !_isExit){
        _condi.wait(uniLk);
    }
    
    ElemType ret;
    if (!empty()) {
        ret = _que.front();
        _que.pop();
        _condi.notify_all();  // 唤醒因队列满而陷入等待的子线程
    }

    // if(_isExit){
    //     return 0;
    // }

    return ret;
}

/**
 * @return bool
 */
bool TaskQueue::full() {
    return _que.size() == _capacity;
}

/**
 * @return bool
 */
bool TaskQueue::empty() {
    return _que.size() == 0;
}

/**
 * @brief 唤醒所有子线程, 准备退出
 * @return void
 */
void TaskQueue::wakeup() {
    _isExit = true;
    _condi.notify_all();
    return;
}